package com.rtsapp.server.gamelog.server.dao;

import com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool;
import com.rtsapp.server.domain.mysql.sql.MySQLPreparedStatement;
import com.rtsapp.server.domain.mysql.sql.MySQLResultSetHandler;
import com.rtsapp.server.gamelog.api.model.*;
import com.rtsapp.server.logger.Logger;
import com.rtsapp.server.logger.LoggerFactory;
import com.rtsapp.server.utils.time.DayPeriodCalendar;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.concurrent.atomic.AtomicInteger;




public class GamelogDao extends BaseLogDao{

    private static final Logger LOG = LoggerFactory.getLogger(GamelogDao.class);

    private final DayPeriodCalendar calendar = new DayPeriodCalendar( 0 );


    public GamelogDao(DatabaseWorkerPool writePool) {
        super( writePool );
    }


    public long queryMaxLogTimeMils(String logName, String gameId, String arenaId, String serverId){

        DatabaseWorkerPool pool = getWorkPool();
        MySQLPreparedStatement preparedStatement =  pool.getPreparedStatement("QUERY_MAX_LOG_TIME_" + logName);
        preparedStatement.setParams(gameId, arenaId, serverId);

        Date maxLogTime = new Date( 0 );

        pool.query(preparedStatement, new MySQLResultSetHandler() {

            @Override
            public void doResultSet(ResultSet rs) {
                try {
                    if (rs.next()) {
                        Timestamp dbTime = rs.getTimestamp(1);
                        if (dbTime != null) {
                            maxLogTime.setTime(dbTime.getTime());
                        }
                    }
                } catch (SQLException e) {
                    LOG.error(e);
                }
            }
        });

        return maxLogTime.getTime();
    }

    public int queryLogCountInDay(String logName, long logTimeMils,   String gameId, String arenaId, String serverId){


        long beginMils =  calendar.getPeriodStartMils( logTimeMils );
        long endMils = calendar.getNextPeriodStartMils( logTimeMils );

        DatabaseWorkerPool pool = getWorkPool();
        MySQLPreparedStatement preparedStatement =  pool.getPreparedStatement("QUERY_LOG_COUNT_BY_TIME_" + logName);

        preparedStatement.setParams(gameId, arenaId, serverId, new Date(beginMils), new Date(endMils)  );

        AtomicInteger maxLogTime = new AtomicInteger(0);

        pool.query(preparedStatement, new MySQLResultSetHandler() {

            @Override
            public void doResultSet(ResultSet rs) {
                try {
                    if (rs.next()) {
                        int logCount = rs.getInt(1);
                        maxLogTime.set(logCount);
                    }
                } catch (SQLException e) {
                    LOG.error(e);
                }
            }
        });

        return maxLogTime.get();
    }




    public void insertLog( String logType , String log ){
        switch ( logType ){

            case "Register":{
                RegisterLog entity =  new RegisterLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Login":{
                LoginLog entity =  new LoginLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Payment":{
                PaymentLog entity =  new PaymentLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "AddItem":{
                AddItemLog entity =  new AddItemLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "CostItem":{
                CostItemLog entity =  new CostItemLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Guide":{
                GuideLog entity =  new GuideLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Level":{
                LevelLog entity =  new LevelLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Action":{
                ActionLog entity =  new ActionLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Activity":{
                ActivityLog entity =  new ActivityLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }
            case "Heartbeat":{
                HeartbeatLog entity =  new HeartbeatLog();
                if( entity.readFrom( log ) ) {
                    insert(entity);
                }else{
                    LOG.error( "log parse error logType={}, log={}", logType, log );
                }
                return;
            }

        }
    }


     public void insert( com.rtsapp.server.gamelog.api.model.RegisterLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_RegisterLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getDevice(),entity.getImei(),entity.getMac(),entity.getResolution(),entity.getOs(),entity.getOsVersion(),entity.getOpenUDID(),entity.getADUDID(),entity.getAPPUDID(),entity.getCENTERID(),entity.getIp(),entity.getChannel()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.LoginLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_LoginLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getDevice(),entity.getImei(),entity.getMac(),entity.getResolution(),entity.getOs(),entity.getOsVersion(),entity.getOpenUDID(),entity.getADUDID(),entity.getAPPUDID(),entity.getCENTERID(),entity.getIp(),entity.getAction(),entity.getLevel(),entity.getVirtualMoney()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.PaymentLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_PaymentLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getRechrageTimes(),entity.getOrderId(),entity.getMoney(),entity.getCurrency(),entity.getResult(),entity.getResultCode(),entity.getProductId(),entity.getProductName(),entity.getProductPrice(),entity.getGetVirualMoney(),entity.getGetVipExp(),entity.getPlayerLevel(),entity.getVirualMoney(),entity.getVipLevel(),entity.getVipExp(),entity.getOldVipLevel()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.AddItemLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_AddItemLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getBehavior(),entity.getItemId(),entity.getItemName(),entity.getItemNum(),entity.getResultNum()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.CostItemLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_CostItemLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getBehavior(),entity.getItemId(),entity.getItemName(),entity.getItemNum(),entity.getResultNum()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.GuideLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_GuideLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getGuideId(),entity.getGuideName()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.LevelLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_LevelLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getOldLevel(),entity.getNewLevel()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.ActionLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_ActionLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getAction(),entity.getActionParam()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.ActivityLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_ActivityLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getUserId(),entity.getRoleId(),entity.getActivityType(),entity.getActivityTypeName(),entity.getActivityCondition(),entity.getActivityConditionName(),entity.getActivityId()} );
            db.execute( stmt );
     }

     public void insert( com.rtsapp.server.gamelog.api.model.HeartbeatLog entity ) {
            com.rtsapp.server.domain.mysql.sql.DatabaseWorkerPool db = getWorkPool( );
            MySQLPreparedStatement stmt = db.getPreparedStatement( "insert_HeartbeatLog" );
            stmt.setParams( new Object[]{entity.getId(),entity.getLogTime(),entity.getGameId(),entity.getAreaId(),entity.getServerId(),entity.getOnlinePlayerNum(),entity.getThroughput(),entity.getSystemTotalMemory(),entity.getSystemFreeMemory(),entity.getJVMMaxMemory(),entity.getJVMTotalMemory(),entity.getJVMFreeMemory()} );
            db.execute( stmt );
     }

     public  boolean prepareStatement( DatabaseWorkerPool db ){
         if( ! db.prepareStatement( "insert_RegisterLog", "insert into RegisterLog(id,logTime,gameId,areaId,serverId,userId,device,imei,mac,resolution,os,osVersion,openUDID,ADUDID,APPUDID,CENTERID,ip,channel) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_LoginLog", "insert into LoginLog(id,logTime,gameId,areaId,serverId,userId,roleId,device,imei,mac,resolution,os,osVersion,openUDID,ADUDID,APPUDID,CENTERID,ip,action,level,virtualMoney) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_PaymentLog", "insert into PaymentLog(id,logTime,gameId,areaId,serverId,userId,roleId,rechrageTimes,orderId,money,currency,result,resultCode,productId,productName,productPrice,getVirualMoney,getVipExp,playerLevel,virualMoney,vipLevel,vipExp,oldVipLevel) values (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_AddItemLog", "insert into AddItemLog(id,logTime,gameId,areaId,serverId,userId,roleId,behavior,itemId,itemName,itemNum,resultNum) values (?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_CostItemLog", "insert into CostItemLog(id,logTime,gameId,areaId,serverId,userId,roleId,behavior,itemId,itemName,itemNum,resultNum) values (?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_GuideLog", "insert into GuideLog(id,logTime,gameId,areaId,serverId,userId,roleId,guideId,guideName) values (?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_LevelLog", "insert into LevelLog(id,logTime,gameId,areaId,serverId,userId,roleId,oldLevel,newLevel) values (?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_ActionLog", "insert into ActionLog(id,logTime,gameId,areaId,serverId,userId,roleId,action,actionParam) values (?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_ActivityLog", "insert into ActivityLog(id,logTime,gameId,areaId,serverId,userId,roleId,activityType,activityTypeName,activityCondition,activityConditionName,activityId) values (?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }
         if( ! db.prepareStatement( "insert_HeartbeatLog", "insert into HeartbeatLog(id,logTime,gameId,areaId,serverId,onlinePlayerNum,throughput,systemTotalMemory,systemFreeMemory,JVMMaxMemory,JVMTotalMemory,JVMFreeMemory) values (?,?,?,?,?,?,?,?,?,?,?,?) " ) ){
             return false;
         }

        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_RegisterLog", "select max(logTime) from  RegisterLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_RegisterLog", "select count(*) from  RegisterLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_LoginLog", "select max(logTime) from  LoginLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_LoginLog", "select count(*) from  LoginLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_PaymentLog", "select max(logTime) from  PaymentLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_PaymentLog", "select count(*) from  PaymentLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_AddItemLog", "select max(logTime) from  AddItemLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_AddItemLog", "select count(*) from  AddItemLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_CostItemLog", "select max(logTime) from  CostItemLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_CostItemLog", "select count(*) from  CostItemLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_GuideLog", "select max(logTime) from  GuideLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_GuideLog", "select count(*) from  GuideLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_LevelLog", "select max(logTime) from  LevelLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_LevelLog", "select count(*) from  LevelLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_ActionLog", "select max(logTime) from  ActionLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_ActionLog", "select count(*) from  ActionLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_ActivityLog", "select max(logTime) from  ActivityLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_ActivityLog", "select count(*) from  ActivityLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }
        if( ! db.prepareStatement( "QUERY_MAX_LOG_TIME_HeartbeatLog", "select max(logTime) from  HeartbeatLog   where gameId=? and areaId=? and serverId=? " ) ){
             return false;
         }

         if( ! db.prepareStatement( "QUERY_LOG_COUNT_BY_TIME_HeartbeatLog", "select count(*) from  HeartbeatLog  where gameId=? and areaId=? and serverId=? and logTime>=? and logTime<?" ) ){
             return false;
         }

         return true;
     }

}